//
//  ScriptParsor.m
//  gong
//
//  Created by echo on 14-1-11.
//  Copyright (c) 2014年 echo. All rights reserved.
//

#import "ScriptParsor.h"
#import "Constants.h"
#import "Place.h"
#import "NPC.h"
#import "UIAlertView+Blocks.h"
#import "AutoRemoveMessageView.h"
#import "GameManager.h"
#import "DanceManager.h"
#import "TaskManager+IsDone.h"
#import "Player.h"
#import "BlockAlertView.h"
#import "UICreator.h"
#import "PositionTools.h"
#import "BoxfishAnimator.h"

#define PlaceDictionary @{@"乐技坊" : @"MusicHouse", @"太后宫" : @"EmperorMotherHouse", @"家" : @"PlayerHouse"}
#define NPCDictionary @{@"我" : @"Player", @"乐师" : @"MusicTeacher", @"皇太后" : @"EmperorMother",\
@"端妃":@"DuanFei", @"华妃":@"HuaFei", @"梅妃":@"MeiFei", @"飞天":@"MusicTeacher", @"飞乐":@"MusicTeacher",\
@"飞燕":@"MusicTeacher"}

@implementation ScriptParsor
{
    int _currentLineIndex;
    Place *_place;
    NSDictionary *_NPCInfo;
    NSMutableArray *_NPCArray;
    
    NSArray *_lineArray;
}

SharedInstanceBuilder(ScriptParsor)

- (void)parse:(NSString*)scriptName
{
    _currentLineIndex = 0;
    
    NSString *fullpath = [[NSBundle mainBundle] pathForResource:scriptName ofType:@"txt" inDirectory:@"Scripts"];
    NSString *scriptContent = [NSString stringWithContentsOfFile:fullpath encoding:NSUTF8StringEncoding error:NULL];
    _lineArray = [scriptContent componentsSeparatedByString:@"\n"];
    
    NSMutableArray *newLineArray = [_lineArray mutableCopy];
    for (int i=0; i<newLineArray.count; i++) {
        NSString *oneLine = newLineArray[i];
        if (0 == oneLine.length || [oneLine hasPrefix:@"//"]) {
            [newLineArray removeObjectAtIndex:i];
            i--;
        }
    }
    
    _lineArray = [newLineArray copy];
    
    // 解析场景名
    if (_lineArray.count > 0) {
        NSString *titleContent = _lineArray[0];
        if ([@"名称" isEqualToString:[self getFlagText:titleContent] ]) {
            // 解析环境
            [self parseEnvironment];
            
            // 解析人物信息
            [self parseNPCs];
            
            // 解析具体的对话
            [self parseTalk];
        }
    }
    
    if ([GameManager sharedInstance].memory) {
//        _currentLineIndex = [GameManager sharedInstance].memory.scriptIndex;
    }
}

- (void)parseTalk
{
    int dialogBeginIndex = 3;
    if (_lineArray.count > dialogBeginIndex) {
        _currentLineIndex = dialogBeginIndex;
        [self parseOneLine:_lineArray[_currentLineIndex]];
    }
}

- (void)parseNPCs
{
    if (_lineArray.count > 2) {
        NSString *NPCInfoText = _lineArray[2];
        if ([@"人物" isEqualToString:[self getFlagText:NPCInfoText]]) {
            id json = [self getJsonFromLineContent:NPCInfoText];
            
            if ([json isKindOfClass:[NSDictionary class]]) {
                _NPCInfo = json;
            }
        }
        
        if (_NPCArray) {
            [_NPCArray removeAllObjects];
        } else {
            _NPCArray = [NSMutableArray array];
        }
    }
}

- (void)parseEnvironment
{
    if (_lineArray.count > 1) {
        NSString *placeInfo = _lineArray[1];
        if ([@"环境" isEqualToString:[self getFlagText:placeInfo]]) {
            id json = [self getJsonFromLineContent:placeInfo];
            
            if ([json isKindOfClass:[NSDictionary class]]) {
                if (json[@"场所"]) {
                    NSString *placeClassName = PlaceDictionary[json[@"场所"]];
                    _place = [(Place*)[NSClassFromString(placeClassName) alloc] init:self.scriptContainerView];
                    [_place create];
                }
            }
        }
    }
}

- (void)parseOneLine
{
    _currentLineIndex++;
    
    if (_currentLineIndex < _lineArray.count) {
        [self parseOneLine:_lineArray[_currentLineIndex]];
    }
}

- (void)parseOneLine:(NSString*)lineContent
{
    if ([GameManager sharedInstance].memory.scriptIndex <= _currentLineIndex) {
        [GameManager sharedInstance].memory.scriptIndex = _currentLineIndex;
    }
    
    if (0 == lineContent.length) {
        return;
    }
    
    if ([@"flag-begin" isEqualToString:[self getFlagText:lineContent]]) {
        [self clearNPCs];
        [self parseOneLine];
    } else if([lineContent hasPrefix:@"@flag"]) {
        [self parseOneLine];
    } else if([@"showNPC" isEqualToString:[self getFlagText:lineContent]]) {
        NSString *info = [self getRealInfo:lineContent];
        NSArray *npcInfoArray = [info componentsSeparatedByString:@"/"];
        
        for (NSString *npcInfo in npcInfoArray) {
            NSArray *array = [npcInfo componentsSeparatedByString:@"#"];
            if (array.count > 0) {
                NSString *npcName = array[0];
                NSString *npcClassName = NPCDictionary[npcName];
                
                if (_NPCInfo[npcName]) {
                    NPC *npc = [(NPC*)[NSClassFromString(npcClassName) alloc] initWithContainer:self.scriptContainerView info:_NPCInfo[npcName]];
                    npc.name = array[0];
                    
                    [_NPCArray addObject:npc];
                    
                    if (array.count > 1) {
                        [npc showWithDescripter:array[1]];
                    } else {
                        [npc show];
                    }
                }
            }
        }
        
        [self parseOneLine];
        
    } else if([@"clearNPC" isEqualToString:[self getFlagText:lineContent]]) {
        NSString *info = [self getRealInfo:lineContent];
        [self clearNPC:info];
    } else if([@"moveNPC" isEqualToString:[self getFlagText:lineContent]]) {
        NSString *info = [self getRealInfo:lineContent];
        [self moveNPC:info];
    } else if([@"selectNPC" isEqualToString:[self getFlagText:lineContent]]) {
        NSArray *selectionArray = [self getJsonFromLineContent:lineContent];
        for (NSDictionary *info in selectionArray) {
            NSString *npcName = info[@"npc"];
            
            for (NPC *npc in _NPCArray) {
                if ([npc.name isEqualToString:npcName]) {
                    npc.canSelect = YES;
                    npc.selectTargetAction = ^(){
                        [self selectResult:info];
                    };
                }
            }
        }
    } else if([@"selection" isEqualToString:[self getFlagText:lineContent]]) {
        NSArray *selectionArray = [self getJsonFromLineContent:lineContent];
        
        NSMutableArray *selectionTextArray = [NSMutableArray array];
        for (NSDictionary *info in selectionArray) {
            [selectionTextArray addObject:info[@"text"]];
        }
        
        BlockAlertView *alert = [BlockAlertView alertWithTitle:@"请选择" message:@""];
        for (int i=0; i<selectionTextArray.count; i++) {
            [alert addButtonWithTitle:selectionTextArray[i] block:^{
                NSDictionary *info = selectionArray[i];
                [self performSelector:@selector(selectResult:) withObject:info afterDelay:1.2];
//                [self selectResult:info];
            }];
        }
        
        [alert show];
        
    } else if([@"affectNPC" isEqualToString:[self getFlagText:lineContent]]) {
        [self affectNPC:[self getRealInfo:lineContent]];
    } else if([@"affectGrade" isEqualToString:[self getFlagText:lineContent]]) {
        [self affectGrade:[self getRealInfo:lineContent]];
    } else if([@"award" isEqualToString:[self getFlagText:lineContent]]) {
        [self showAward:[self getRealInfo:lineContent]];
    } else if([@"action" isEqualToString:[self getFlagText:lineContent]]) {
        [self parseAction:[self getRealInfo:lineContent]];
    } else if([@"taskDone" isEqualToString:[self getFlagText:lineContent]]){
        NSString *taskName = [self getRealInfo:lineContent];
        [[NSNotificationCenter defaultCenter] postNotificationName:MsgTaskIsDone object:nil userInfo:@{TaskNameKey:taskName}];
        [self parseOneLine];
    } else if([@"goto" isEqualToString:[self getFlagText:lineContent]]) {
        NSString *flagName = [self getRealInfo:lineContent];
        [self gotoFlagByFlagName:flagName];
    }else if([@"return" isEqualToString:[self getFlagText:lineContent]]) {
        [_place leave];
        [self clearNPCs];
        [[GameManager sharedInstance] gotoStreet];
    } else { //对话
        NSMutableString *newLineContent = [lineContent mutableCopy];
        [newLineContent replaceOccurrencesOfString:@"{myname}"
                                        withString:[Player sharedInstance].name
                                           options:NSCaseInsensitiveSearch
                                             range:NSMakeRange(0, newLineContent.length)];
        lineContent = [newLineContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        NSLog(@"%@", lineContent);
        
        NSString *npcName = [self getFlagText:lineContent];
        NPC *talkingNPC;
        for (NPC *npc in _NPCArray) {
            if ([npcName hasPrefix:npc.name]) {
                talkingNPC = npc;
            }
        }
        
        lineContent = [self getTalkInfo:lineContent];
               
        if (talkingNPC) {
            [talkingNPC talk:lineContent];
        } else {
            [_place showTalk:lineContent npc:talkingNPC];
        }
        
        if ([npcName hasSuffix:@"auto"]) {
            [self parseOneLine];
        }
    }
}

- (void)selectResult:(NSDictionary*)info
{
    if (info[@"health"]) {
        NSString *msg = @"";
        msg = [self composePlayerParamerMsg:msg parameterName:@"体力" json:info key:@"health"];
        [AutoRemoveMessageView show:msg withContainerView:self.scriptContainerView completion:nil];
    }
    
    if (info[@"awardBradge"]) {
        NSString *msg = [NSString stringWithFormat:@"你获得了%@的称号", info[@"awardBradge"]];
        [AutoRemoveMessageView show:msg withContainerView:self.scriptContainerView completion:nil];
    }
    
    if (info[@"taskDone"]) {
        [[NSNotificationCenter defaultCenter] postNotificationName:MsgTaskIsDone object:nil userInfo:@{TaskNameKey:info[@"taskDone"]}];
    }
    
    if (info[@"affectNPC"]) {
        NSString *affectInfo = info[@"affectNPC"];
        [self affectNPC:affectInfo action:@selector(gotoFlag:) parameter:info];
    } else {
        [self gotoFlag:info];
    }
}

- (void)moveNPC:(NSString*)info
{
    NSArray *array = [info componentsSeparatedByString:@"#"];
    for (NPC *npc in _NPCArray) {
        if ([npc.name isEqualToString:array[0]]) {
            [npc moveTo:array[1]];
        }
    }
    [self parseOneLine];
}

- (void)clearNPC:(NSString*)info
{
    NSArray *array = [info componentsSeparatedByString:@"/"];
    for (NSString *name in array) {
        for (NPC *npc in _NPCArray) {
            if ([npc.name isEqualToString:name]) {
                [npc leave];
            }
        }
    }
    [self parseOneLine];
}

- (void)parseAction:(NSString*)actionInfo
{
    NSData *data = [actionInfo dataUsingEncoding:NSUTF8StringEncoding];
    id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    
    if ([json isKindOfClass:[NSDictionary class]]) {
        NSString *msg = @"";
        msg = [self composePlayerParamerMsg:msg parameterName:@"体力" json:json key:@"health"];
        msg = [self composePlayerParamerMsg:msg parameterName:@"舞艺" json:json key:@"danceSkill"];
        msg = [self composePlayerParamerMsg:msg parameterName:@"银子" json:json key:@"silver"];
        
        if (msg.length > 0) {
            [AutoRemoveMessageView show:msg withContainerView:self.scriptContainerView completion:^{
                [self doAction:json];
            }];
        } else {
            [self doAction:json];
        }
    }
}

- (void)doAction:(id)json
{
    if ([json isKindOfClass:[NSDictionary class]]) {
        if (NSOrderedSame == [@"dance" caseInsensitiveCompare:json[@"name"]]) {
            [[DanceManager sharedInstance] dance];
        } else if (NSOrderedSame == [@"learnDance" caseInsensitiveCompare:json[@"name"]]) {
            [[DanceManager sharedInstance] learnDance];
        }
    }
}

- (NSString*)composePlayerParamerMsg:(NSString*)msg parameterName:(NSString*)parameterName json:(id)json key:(NSString*)key
{
    NSString *text = [self getPlayerParameterMsg:parameterName json:json key:key];
    if(text){
        return [msg stringByAppendingString:text];
    } else {
        return msg;
    }
}

- (NSString*)getPlayerParameterMsg:(NSString*)parameterName json:(id)json key:(NSString*)key
{
    NSString *msg;

    if ([json isKindOfClass:[NSDictionary class]]) {
        if (json[key]) {
            int value = [json[key] integerValue];
            if (value > 0) {
                msg = [NSString stringWithFormat:@"你的%@增加了%i\n", parameterName, value];
            } else {
                msg = [NSString stringWithFormat:@"你的%@减少了%i\n", parameterName, -value];
            }
        }
    }
    
    return msg;
}

- (void)showAward:(NSString*)awardInfo
{
    [self notifyClearTalk];
    
    NSArray *awardArray = [awardInfo componentsSeparatedByString:@"/"];
    
    NSString *showMsg = @"";
    for (NSString *oneInfo in awardArray) {
        NSArray *array = [oneInfo componentsSeparatedByString:@"~"];
        NSString *awardName = array[0];
        int awardCount = [array[1] integerValue];
        NSString *giver = array[2];
        
        showMsg = [NSString stringWithFormat:@"%@%@赏给了你%i个%@\n", showMsg, giver, awardCount, awardName];
    }
    
    [[GameManager sharedInstance] showAward:showMsg];
}

- (void)affectGrade:(NSString*)affectInfo
{
    NSArray *array = [affectInfo componentsSeparatedByString:@"~"];
    NSString *showMsg = [NSString stringWithFormat:@"你被%@为%@", array[1], array[0]];
    [AutoRemoveMessageView show:showMsg withContainerView:self.scriptContainerView completion:nil];
}

- (void)affectNPC:(NSString*)affectInfo
{
    [self affectNPC:affectInfo action:nil parameter:nil];
}

- (void)notifyClearTalk
{
    [[NSNotificationCenter defaultCenter] postNotificationName:MsgClearTalk object:nil];
}

- (void)affectNPC:(NSString*)affectInfo action:(SEL)action parameter:(id)parameter
{
    [self notifyClearTalk];
    
    NSArray *affectArray = [affectInfo componentsSeparatedByString:@"/"];
    NSString *showMsg = @"";

    for (NSString *oneInfo in affectArray) {
        NSArray *array = [oneInfo componentsSeparatedByString:@"~"];
        NSString *name = array[0];
        NSInteger value = [array[1] integerValue];
        
        if (value >= 0) {
            showMsg = [NSString stringWithFormat:@"%@%@对%@的好感增加了%i\n", showMsg, name, [Player sharedInstance].name, value];
        } else {
            showMsg = [NSString stringWithFormat:@"%@%@对%@的好感减少了%i\n", showMsg, name, [Player sharedInstance].name, value];
        }
    }
    
    [self revealMessage:showMsg duration:5];
}

- (void)revealMessage:(NSString*)message duration:(float)duration
{
    UIFont *font = [UIFont systemFontOfSize:60];
    float widthLimit = self.scriptContainerView.frame.size.width - 80;
    CGSize size = [message sizeWithFont:font constrainedToSize:CGSizeMake(widthLimit, MAXFLOAT)];
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
    [PositionTools placeView:label atTheCenterOfTheView:self.scriptContainerView];
    
    label.backgroundColor = [UIColor clearColor];
    label.text = message;
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor = [UIColor whiteColor];
    label.shadowColor = [UIColor blackColor];
    label.shadowOffset = CGSizeMake(2, 2);
    label.font = font;
    label.numberOfLines = 0;
    label.lineBreakMode = NSLineBreakByWordWrapping;
    
    [BoxfishAnimator revealFromLeftByView:label duration:duration isAutoRemove:YES];
}

- (void)gotoFlag:(NSDictionary*)info
{
    [self gotoFlagByFlagName:info[@"goto"]];
}

- (void)gotoFlagByFlagName:(NSString*)flagName
{
    if (flagName) {
        [self setLineIndexByFlag:flagName];
        
        if ([@"begin" isEqualToString:flagName]) {
            [self clearNPCs];
        }
        
        [self parseOneLine];
    }
}

- (void)clearNPCs
{
    for (NPC *npc in _NPCArray) {
        [npc leave];
    }
    
    [_NPCArray removeAllObjects];
}

- (id)getJsonFromLineContent:(NSString*)lineContent
{
    lineContent = [self getRealInfo:lineContent];
    
    NSData *data = [lineContent dataUsingEncoding:NSUTF8StringEncoding];
    id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    NSLog(@"info is %@", json);
    return json;
}

- (NSString*)getFlagText:(NSString*)lineContent
{
    NSString *flagText;
    if (lineContent.length > 0) {
        if ([@"@" isEqualToString:[lineContent substringToIndex:1]]) {
            NSRange range = [lineContent rangeOfString:@"="];
            if (0 == range.length) {
                flagText = [lineContent substringFromIndex:1];
            } else {
                flagText = [lineContent substringWithRange:NSMakeRange(1, range.location - 1)];
            }
        } else {
            NSRange range = [lineContent rangeOfString:@"："];
            flagText = [lineContent substringWithRange:NSMakeRange(0, range.location)];
        }
    }
    
    flagText = [flagText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    return flagText;
}

- (NSString*)getRealInfo:(NSString*)lineContent
{
    return [self getRealInfo:lineContent seperator:@"="];
}

- (NSString*)getTalkInfo:(NSString*)lineContent
{
    return [self getRealInfo:lineContent seperator:@"："];
}

- (NSString*)getRealInfo:(NSString*)lineContent seperator:(NSString*)seperator
{
    NSString *realInfo;
    if (lineContent.length > 0) {
        NSRange range = [lineContent rangeOfString:seperator];
        if (range.location > 0) {
            realInfo = [lineContent substringFromIndex:range.location + 1];
        }
    }
    
    return realInfo;
}

- (void)setLineIndexByFlag:(NSString*)flag
{
    for (int i=0; i<_lineArray.count; i++) {
        if ([flag isEqualToString:[self getFlagText:_lineArray[i]]]) {
            _currentLineIndex = i;
            return;
        }
    }
}

@end
